//
//  LRHomeController.swift
//  LRWeibo
//
//  Created by 雷路荣 on 15/12/15.
//  Copyright © 2015年 leilurong. All rights reserved.
//

import UIKit

import SVPullToRefresh

/// cell的缓存重用标识
enum LRStatusCellReuseIdentifier: String {
    case StatuesOriginalCell = "StatuesOriginalCell" //原创微博标识
    case StatuesTransmitCell = "StatuesTransmitCell" //转发微博标识
}

// tableView cell 的高度想通过cell里面的内容来自适应
// 1.需要给contentView添加约束,让contentView的高度参照里面的内容来自动更改高度(需要添加顶部和底部约束)
// 2.设置cell预估行高
// 3.设置cell行高根据约束来自适应
class LRHomeController: LRBaseViewController, LRStatuesCellDelegate {
    
    /// tipLabel的高度  tipLabel用于显示下拉刷新加载了几条新微博
    let tipLabelHeight: CGFloat = 44
    //模型数组属性
    var statues: [LRStatues]? {
        didSet{
            self.tableView.reloadData()
        }
    }
    //MARK: - 重用标示
    //private let reuseIdentifier = "LRStatuesCell"
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        //如果用户没有登录，不执行后面
        if !LRUserAccount.userLogin {
            return
        }
        
        //添加导航栏上面的标题按钮和左右两边的按钮
        setNavigationItem()
        
        //设置tableView参数及注册cell
        prepareForTabView()
        
        //添加下拉刷新控件，实现相关方法
        setRefreshControl()
       
        // 监听配图点击事件
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "selectPicture:", name: LRCellPictureViewSelectNotification, object: nil)
        // 监听popover消失
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "popoverVcDismiss", name: LRPresentationControllerDismissNotification, object: nil)
    }
    //popover消失回调方法，将标题按钮箭头转回去
    func popoverVcDismiss(){
        //获取按钮
        let button = navigationItem.titleView as! LRHomeTitleButton
        
        titleButtonDidClick(button)
    }
    // 配图点击回调
    func selectPicture(notification: NSNotification) {
        print("notification = %@",notification)
        // 获取通知里面的信息
        guard let indexPath = notification.userInfo?[LRCellPictureViewSelectIndexPathKey] as? NSIndexPath else {
            print("indexPath 为空.")
            return
        }
        // 获取到大图的数组
        guard let models = notification.userInfo?[LRCellPictureViewSelectModelsKey] as? [LRPhotoBrowserModal] else {
            print("大图的数组为空")
            return
        }
        // 打开照片浏览器
        let photoBrowserVc = LRPhotoBrowserController(indexPath: indexPath, models: models)
        // 实现照片选择器的转场动画
        // 不能使用self作为转场代理,因为self已经成为了标题栏按钮的的转场动画
        photoBrowserVc.transitioningDelegate = photoBrowserVc
        photoBrowserVc.modalPresentationStyle = UIModalPresentationStyle.Custom
        
        presentViewController(photoBrowserVc, animated: true, completion: nil)
    }

    private func prepareForTabView() {
        //self.tableView.rowHeight = 198
        // 设置cell预估行高
        self.tableView.estimatedRowHeight = 168
        // 设置cell行高根据约束来自适应
        //tableView.rowHeight = UITableViewAutomaticDimension
        // 取出分割线
        tableView.separatorStyle = UITableViewCellSeparatorStyle.None
        tableView.registerClass(LRStatuesOriginalCell.self, forCellReuseIdentifier: LRStatusCellReuseIdentifier.StatuesOriginalCell.rawValue)
        //MARK: - 注册转发cell
        tableView.registerClass(LRStatuesTransmitCell.self, forCellReuseIdentifier: LRStatusCellReuseIdentifier.StatuesTransmitCell.rawValue)
        // 不添加这个闭包tableView不会出现菊花,只有添加闭包,当拖动到最后一个cell时会出现菊花,执行闭包
        // 添加上拉加载更多数据的事件(闭包),当拖动到最后一个cell的时候会调用这个闭包
        tableView.addInfiniteScrollingWithActionHandler { () -> Void in
            print("上拉加载更多数据")
            self.loadMoreStatus()
        }
        // 先不显示上拉加载更多的菊花
        tableView.showsInfiniteScrolling = false
    }
    /// 显示下拉刷新了多少条数据
    private func showTipLabelView(count: Int) {
        //显示下拉刷新了多少条数据
        tipLabel.text = count==0 ? "没有加载到新的微博数据" : "加载了\(count)条微博数据"
        // 添加到导航栏层级下方
        navigationController?.navigationBar.insertSubview(tipLabel, atIndex: 0)
        //动画
        UIView.animateWithDuration(0.5, animations: { () -> Void in
            self.tipLabel.frame.origin.y = self.tipLabelHeight
            }) { (_) -> Void in
                UIView.animateWithDuration(0.5, delay: 1, options: UIViewAnimationOptions(rawValue: 0), animations: { () -> Void in
                    self.tipLabel.frame.origin.y = -(self.tipLabelHeight+20)
                    }, completion: { (_) -> Void in
                        //self.tipLabel.removeFromSuperview()
                        print("显示加载了几条数据完成")
                })
        }
    }
    
    //添加下拉刷新控件，实现相关方法
    private func setRefreshControl() {
        // 默认的宽度为屏幕的宽度,高度60. frame = (0 0; 375 60)
        refreshControl = LRRefreshControl()
        //print("refreshControl = \(refresh)")
        refreshControl?.addTarget(self, action: "loadNewStatus", forControlEvents: UIControlEvents.ValueChanged)
        // 主动进入刷新状态,只会让刷新控件界面显示刷新,并不会主动触发 UIControlEvents.ValueChanged 事件
        refreshControl?.beginRefreshing()
        // 主动触发 UIControlEvents.ValueChanged
        refreshControl?.sendActionsForControlEvents(UIControlEvents.ValueChanged)
    }
    //MARK: - 加载最新微博数据
    func loadNewStatus(){
        // 如果没有微博数据, since_id设置为0,加载最新的20条
        // 如果有微博数据,获取最大id的微博
        let since_id = statues?.first?.id ?? 0 // first 加载最新的
        let max_id = 0
        LRStatues.loadStatues(since_id, max_id: max_id) { (statues, error) -> () in
            // 关闭上拉加载更多数据的控件
            self.refreshControl?.endRefreshing()
            
            if error != nil {
                print("加载微博数据出错")
                return
            }
            
            let count = statues?.count ?? 0
            // 判断如果是下拉刷新,显示下拉刷新了多少条数据
            if since_id > 0{
                self.showTipLabelView(count)
            }
            if count == 0 {
                // 没有加载到数据
                print("没有加载到数据")
                return
            }
            // 如果是下拉刷新,将获取到的新数据,拼接在现有数据的前面
            if since_id > 0 {
                // 表示下拉刷新 最终数据 = 新数据 + 现有数据
                self.statues = statues! + self.statues!
                print("下拉刷新 加载到 \(count)条新数据")
            }else {// 第一次进入程序,加载最新的20条数据
                self.statues = statues
                print("第一次进入程序, 加载了 \(count) 条微博数据")
                // 需要显示上拉加载更多地菊花
                self.tableView.showsInfiniteScrolling = true
            }
            print("总共有多少条数据: \(self.statues?.count)")

        }
    }
    
    //MARK: - 上拉加载更多数据
    private func loadMoreStatus() {
        let since_id = 0
        let max_id = statues?.last?.id ?? 0 // last加载后面的
        LRStatues.loadStatues(since_id, max_id: max_id) { (statues, error) -> () in
            // 关闭上拉加载更多数据的控件
            self.tableView.infiniteScrollingView.stopAnimating()
            if error != nil {
                print("上拉加载数据出错了")
                return
            }
            // 没有出错
            let count = statues?.count ?? 0
            if count == 0 {
                // 没有加载到数据
                print("没有加载到数据")
                return
            }
            // 加载到了数据
            if max_id > 0 {
                // 最终的数据 = 现有数据 + 获取到的数据
                self.statues = self.statues! + statues!
                print("上拉加载到更多数据: \(count)条")
            }
            print("总共有多少条数据: \(self.statues?.count)")
        }
    }
    
    //MARK: - 添加导航栏上面的标题按钮和左右两边的按钮
    private func setNavigationItem() {
        //设置导航栏按钮
        navigationItem.leftBarButtonItem = UIBarButtonItem(imageName: "navigationbar_friendsearch")
        navigationItem.rightBarButtonItem = UIBarButtonItem(imageName: "navigationbar_pop")
        // ??: `xx ?? yy`: 表示 ?? 前面可选如果有值,会强制拆包,并且返回这个值, ??前面可选没有值,会返回?? 后面的值
        let title = LRUserAccount.loadUserAccount()?.screen_name ?? "没获取到用户名"
        //标题按钮
        let titleButton = LRHomeTitleButton(title: title)
        titleButton.addTarget(self, action: "titleButtonDidClick:", forControlEvents: UIControlEvents.TouchUpInside)
        navigationItem.titleView = titleButton
    }
    //MARK: - 标题按钮点击
    @objc private func titleButtonDidClick(button: UIButton){
        //点击选择状态取反
        button.selected = !button.selected
        //UIView动画 大于等于M_PI顺时针旋转，小于则逆时针旋转
        UIView.animateWithDuration(0.25) { () -> Void in
            button.imageView?.transform = button.selected ? CGAffineTransformMakeRotation(CGFloat(M_PI)-0.001) : CGAffineTransformIdentity //原路还原状态
        }
        //如果按钮选中才弹出
        if button.selected {
            //通过UIStoryboard取出箭头指向控制器
            let sb = UIStoryboard(name: "LRPopover", bundle: nil)
            let popVc = sb.instantiateViewControllerWithIdentifier("PopoverID")
            // 直接modal出来大小是和屏幕一样大小.需要通过自定义转场动画来控制modal出来的控制器的view的大小
            // 1. modal出来的控制器实现代理
            popVc.transitioningDelegate = self
            // 2. 设置modal的样式为自定的样式,如果不设置modalPresentationStyle modal出来控制器时,背后的控制器是不在.设置为UIModalPresentationStyle.Custom时,背后的控制器的view还处于显示状态,作用是让我们的转场动画元素丰富
            popVc.modalPresentationStyle = UIModalPresentationStyle.Custom
            //弹出
            presentViewController(popVc, animated: true, completion: nil)
        }
        
        
    }
    
    //MARK: - tableView数据源和代理----------------------------------
    
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // 如果statuses没有数据,返回0
        return self.statues?.count ?? 0
    }
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let statues = self.statues![indexPath.row]
        let cell = tableView.dequeueReusableCellWithIdentifier(statues.cellID(), forIndexPath: indexPath) as! LRStatuesCell
        cell.statues = statues
        //设置代理
        cell.delegate = self
        return cell
    }
    //返回行高
    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        //取出对应cell的模型数据
        let statues = self.statues![indexPath.row]
        //使用cell计算行高,每次都计算行高需要消耗性能,将行高进行缓存,行高是根据模型算出来的.行高缓存在模型中最合适
        //如果对应行的模型数据（缓存）中有行高值，直接使用缓存的行高,不再执行后面的计算
        if statues.rowHeight != nil {
            return statues.rowHeight!
        }
        // 调用这个方法,会再次调用heightForRowAtIndexPath：本方法来获取行高,会出现递归.
        //let cell = tableView.dequeueReusableCellWithIdentifier(ReuseIdentifier, forIndexPath: indexPath) as! CZStatusCell
        let cell = tableView.dequeueReusableCellWithIdentifier(statues.cellID()) as! LRStatuesCell
        //计算行高
        let rowHeight = cell.rowHeight(statues)
        // 保存计算好的行高
        statues.rowHeight = rowHeight
        //print("rowHeight:\(rowHeight)")
        return rowHeight
    }
    //点击某一cell
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        //取消选择
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
        //获取点击cell的数据
        let statues = self.statues![indexPath.row]
        //跳转待微博详情控制器
        showDetailStatusViewController(statues)
    }
    
    ///MARK: - LRStatuesCellDelegate 转发微博cell的点击代理方法
    func retweetedStatusDidClick(statues: LRStatues) {
        //print("retweetedStatusDidClick")
        //跳转到微博详情控制器
        showDetailStatusViewController(statues)
    }
    //MARK: - 自定义方法 跳转到微博详情控制器
    private func showDetailStatusViewController(statues: LRStatues) {
        let detaiVc = LRStatusDetailViewController(statues: statues)
        //隐藏底部tabBar
        detaiVc.hidesBottomBarWhenPushed = true
        navigationController?.pushViewController(detaiVc, animated: true)
    }
    
    //MARK: - 懒加载
    /// 显示加载了几条新微博的view
    private lazy var tipLabel: UILabel = {
        //一开始在状态栏顶部 状态栏高20
        let label = UILabel(frame: CGRectMake(0, -(self.tipLabelHeight + 20), UIScreen.mainScreen().bounds.width, self.tipLabelHeight))
        label.backgroundColor = UIColor.orangeColor()
        label.textColor = UIColor.whiteColor()
        label.textAlignment = NSTextAlignment.Center
        label.font = UIFont.systemFontOfSize(16)
        return label
    }()
}

//MARK: - 扩展 实现transitioningDelegate代理方法

extension LRHomeController: UIViewControllerTransitioningDelegate {
    //返回一个控制展现的对象，这对象可以设置modal出来的控制器view的大小
    func presentationControllerForPresentedViewController(presented: UIViewController, presentingViewController presenting: UIViewController, sourceViewController source: UIViewController) -> UIPresentationController? {
        //需要返回一个UIPresentationController对象，现在我们没有，需要创建一个类继承他
        return LRPresentationController(presentedViewController: presented, presentingViewController: presenting)
    }
    ///返回一个控制modal时的动画的对象
    func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        // 1.创建一个类实现UIViewControllerAnimatedTransitioning
        // 2.用这个类创建对象,并返回回去
        return LRPopoverAnimation()
    }
    /// 返回一个控制dismiss时的动画的对象
    func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        // 1.创建一个类实现UIViewControllerAnimatedTransitioning
        // 2.用这个类创建对象,并返回回去
        return LRDismissAnimation()
    }
}





























































